package com.seleniti.enpareja.web.appbase.client.control.navigation;

import org.ioc.commons.flowcontrol.placecontroller.IsPlace;
import org.ioc.commons.impl.gwt.client.flowcontrol.activitymapper.GoPlace;
import org.ioc.commons.impl.gwt.client.flowcontrol.activitymapper.GoPlace.Tokenizer;
import org.ioc.commons.impl.gwt.client.flowcontrol.placecontroller.GwtPlaceController.PlaceMapper;

import com.google.gwt.core.client.GWT;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceHistoryMapperWithFactory;
import com.google.gwt.user.client.Window;
import com.seleniti.enpareja.controller.control.place.EnParejaPlace;

interface TokenizerFactory {
	GoPlace.Tokenizer<EnParejaPlace> getGoPlaceTokenizer();
	
	SettingsPlace.Tokenizer getSettingsPlaceTokenizer();
}

public class AppPlaceMapper implements PlaceMapper, TokenizerFactory {

	private final HistoryMapper historyMapper;

	public static interface HistoryMapper extends PlaceHistoryMapperWithFactory<TokenizerFactory> {

	}

	public AppPlaceMapper() {
		this.historyMapper = GWT.create(HistoryMapper.class);
		this.historyMapper.setFactory(this);
	}

	public HistoryMapper getHistorymapper() {
		return historyMapper;
	}

	@Override
	public <P extends Enum<? extends IsPlace>> Place getPlace(P place, Object... params) {
		EnParejaPlace epPlace = (EnParejaPlace) place;

		/**
		 * If we haven't specified the resetView parameters, it will be true by
		 * default
		 */
		boolean resetView = (params.length >= 1) ? Boolean.valueOf((Boolean) params[0]) : true;

		/**
		 * The views may have a sub-place token for handling internal subviews.
		 */
		String subPlaceToken = (params.length >= 2 && params[1] != null) ? String.valueOf(params[1]) : null;

		switch (epPlace) {
		case LoginPlace:
			EnParejaPlace placeWhenLoginOk = null;

			try {
				placeWhenLoginOk = (params.length >= 3 && params[2] != null) ? EnParejaPlace.valueOf(String
						.valueOf(params[2])) : null;
			} catch (Exception e) {
				placeWhenLoginOk = null;
			}

			String userEmail = null;
			if (params.length >= 4) {
				userEmail = (String) params[3];
			}

			return new LoginPlace(epPlace, resetView, subPlaceToken, placeWhenLoginOk, userEmail);
		case UserSettings:
			boolean passwordChangeEnabled;
			try {
				passwordChangeEnabled = (params.length >= 3 && params[2] != null) ? Boolean.valueOf(String
						.valueOf(params[2])) : null;
			} catch (Exception e) {
				passwordChangeEnabled = true;
			}

			boolean showDownloadAppWhenPassword;
			try {
				showDownloadAppWhenPassword = (params.length >= 4 && params[3] != null) ? Boolean.valueOf(String
						.valueOf(params[3])) : null;
			} catch (Exception e) {
				showDownloadAppWhenPassword = false;
			}
			return new SettingsPlace(epPlace, resetView, subPlaceToken, passwordChangeEnabled,
					showDownloadAppWhenPassword);
		case ExternalLoginPlace:
			String externalLoginUrl = (String) params[2];
			Window.Location.replace(externalLoginUrl);
			return null;
		default:

			return new GoPlace<EnParejaPlace>(epPlace, resetView, subPlaceToken);

		}
	}

	@Override
	public Tokenizer<EnParejaPlace> getGoPlaceTokenizer() {
		return new GoPlace.Tokenizer<EnParejaPlace>(EnParejaPlace.class);
	}
	
	@Override
	public com.seleniti.enpareja.web.appbase.client.control.navigation.SettingsPlace.Tokenizer getSettingsPlaceTokenizer() {
		return new SettingsPlace.Tokenizer();
	}

}
